﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace RectangleReport
{
    class Program
    {
        private static readonly Hashtable[] Reports = new Hashtable[4];
        private static readonly int[] StartPos = new[] {0, 50, 75, 35};

        static void Main(string[] args)
        {
            // парсим 4 файла логов
            for (var i = 0; i < 4; ++i)
            {
                var reader = new StreamReader("../../start" + (i + 1) + ".ini");
                Reports[i] = new Hashtable();
                string line;
                double count = 0;
                var rectangles = new List<long>();
                while((line = reader.ReadLine()) != null)
                {
                    // получение номера картинки на определенном шаге
                    var regex = new Regex("line(\\d)\\=(\\d+)");
                    var match = regex.Match(line);
                    if (match.Groups.Count == 3)
                    {
                        switch (match.Groups[1].ToString())
                        {
                            case "1":
                                count = 0;
                                count += (int.Parse(match.Groups[2].ToString()) - StartPos[i])*Math.Pow(128, 4);
                                break;
                            case "2":
                                count += int.Parse(match.Groups[2].ToString())*Math.Pow(128, 3);
                                break;
                            case "3":
                                count += int.Parse(match.Groups[2].ToString())*Math.Pow(128, 2);
                                break;
                            case "4":
                                count += int.Parse(match.Groups[2].ToString())*128;
                                break;
                            case "5":
                                count += int.Parse(match.Groups[2].ToString());
                                break;
                        }
                    }
                    // информация о количестве прямоугольников
                    regex = new Regex("rectangleP(\\d)D(\\d)\\=(\\d+)");
                    match = regex.Match(line);
                    if (match.Groups.Count == 4)
                    {
                        var tens = Convert.ToInt32(match.Groups[1].ToString());
                        var ones = Convert.ToInt32(match.Groups[2].ToString());
                        
                        if (tens == 0 && ones == 0)
                            rectangles = new List<long>();

                        rectangles.Add(long.Parse(match.Groups[3].ToString()));

                        if (tens == 2 && ones == 5)
                        {
                            Reports[i].Add(count, rectangles);
                        }
                    }
                }
            }

            var keys = new ArrayList[4];

            var SPEED = new double[4];
            var PERSENT = 0.0;

            // получение скорости работы программы и общего процента выполнения
            for (var i = 0; i < 4; ++i)
            {
                keys[i] = new ArrayList();
                keys[i].AddRange(Reports[i].Keys);
                keys[i].Sort();

                var count = (double) keys[i][0];
                for (var j = 1; j < keys[i].Count; ++j)
                {
                    count += ((double) keys[i][j] - (double)keys[i][j - 1]);
                }

                SPEED[i] = count/keys[i].Count;
                PERSENT += (double) keys[i][keys[i].Count - 1];
            }

            PERSENT /= Math.Pow(2, 42);

            var writer = new StreamWriter[18];
            var writerTypes = new StreamWriter[3];
            var total = new StreamWriter("total.log");
            long totalItem = 0;
            var lastItems = new long[18];
            var lastItemsType = new long[3];
            // логи по разновидностям прямоугольников на картинке
            for (var i = 0; i < 18; ++i)
            {
                writer[i] = new StreamWriter("rectangle" + i + ".log");
                lastItems[i] = 0;
            }

            for (var i = 0; i < 3; ++i)
            {
                writerTypes[i] = new StreamWriter("types" + i + ".log");
                lastItemsType[i] = 0;
            }

            double len = 0;
            for (var i = 0; i < 4; ++i)
            {
                // вывод всех различных прямоугольников
                var iid = 0;
                while (keys[i].Count > iid)
                {
                    var items = (List<long>)Reports[i][keys[i][iid]];
                    for (var j = 0; j < 18; ++j)
                    {
                        writer[j].WriteLine("{0}: {1}", (double)keys[i][iid] + len, items[j] + lastItems[j]);
                    }

                    long count = 0;
                    for (var j = 1; j < 6; ++j)
                    {
                        count += items[j];
                    }
                    writerTypes[0].WriteLine("{0}: {1}", (double)keys[i][iid] + len, count + lastItemsType[0]);
                    count = items[6] + items[12] + lastItemsType[1];
                    writerTypes[1].WriteLine("{0}: {1}", (double)keys[i][iid] + len, count + lastItemsType[1]);
                    count = 0;
                    for (var j = 7; j < 12; ++j)
                    {
                        count += items[j];
                    }
                    writerTypes[2].WriteLine("{0}: {1}", (double)keys[i][iid] + len, count + lastItemsType[2]);

                    count = 0;
                    for (var j = 1; j < 18; ++j)
                    {
                        count += items[j];
                    }
                    total.WriteLine("{0}: {1}", (double)keys[i][iid] + len, count + totalItem);

                        iid += 10;
                }
                var lastItem = (double)keys[i][keys[i].Count - 1];
                var lItems = (List<long>)Reports[i][lastItem];
                for (var j = 0; j < 18; ++j)
                {
                    lastItems[j] += lItems[j];
                }

                for (var j = 1; j < 6; ++j)
                {
                    lastItemsType[0] += lItems[j];
                }
                lastItemsType[1] = lItems[6] + lItems[12] + lastItemsType[1];
                for (var j = 7; j < 12; ++j)
                {
                    lastItemsType[2] += lItems[j];
                }

                for (var j = 1; j < 18; ++j)
                {
                    totalItem += lItems[j];
                }

                len += lastItem;
            }

            for (var i = 0; i < 18; ++i)
            {
                writer[i].Close();
            }

            for (var i = 0; i < 3; ++i)
            {
                writerTypes[i].Close();
            }

            total.Close();

            var summary = new StreamWriter("summary.log");
            summary.WriteLine(PERSENT);
            summary.WriteLine(SPEED[0]);
            summary.WriteLine(SPEED[1]);
            summary.WriteLine(SPEED[2]);
            summary.WriteLine(SPEED[3]);
            summary.Close();
        }
    }
}
